// SQL日志解析核心模块

// 解析SQL日志的核心函数（支持多线程日志）
export function parseSQLLog(logContent) {
  const lines = logContent.split('\n')
  const sqlStatements = []
  const threadContexts = new Map() // 存储每个线程的解析上下文

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i].trim()
    
    // 跳过空行和Total行
    if (!line || line.includes('<==') || line.includes('Total:')) {
      continue
    }
    
    // 提取线程ID
    const threadId = extractThreadId(line)
    
    // 获取或创建该线程的上下文
    if (!threadContexts.has(threadId)) {
      threadContexts.set(threadId, { preparing: null, parametersList: [] })
    }
    const context = threadContexts.get(threadId)
    
    // 识别Preparing行
    if (line.includes('Preparing:')) {
      const newPreparing = extractPreparing(line)
      
      // 如果是相同的Preparing语句，继续收集参数（批量操作）
      if (context.preparing === newPreparing) {
        // 相同SQL，继续收集参数，不处理之前的SQL
        continue
      }
      
      // 如果是不同的Preparing语句且该线程有未完成的SQL，先处理
      if (context.preparing && context.parametersList.length > 0) {
        if (context.parametersList.length === 1) {
          sqlStatements.push(processSQLStatement(context.preparing, context.parametersList[0]))
        } else {
          sqlStatements.push(processBatchSQLStatement(context.preparing, context.parametersList))
        }
      }
      
      context.preparing = newPreparing
      context.parametersList = []
    }
    
    // 识别Parameters行
    else if (line.includes('Parameters:')) {
      const params = extractParameters(line)
      if (context.preparing) {
        context.parametersList.push(params)
      }
    }
    
    // 遇到其他类型的日志行时，检查是否需要处理已收集的SQL
    else if (context.preparing && context.parametersList.length > 0) {
      // 判断是否应该结束当前SQL的收集
      const shouldEndSQL = shouldEndSQLCollection(line, context)
      
      if (shouldEndSQL) {
        if (context.parametersList.length === 1) {
          sqlStatements.push(processSQLStatement(context.preparing, context.parametersList[0]))
        } else {
          sqlStatements.push(processBatchSQLStatement(context.preparing, context.parametersList))
        }
        context.preparing = null
        context.parametersList = []
      }
    }
  }

  // 处理所有线程的未完成SQL
  for (const [threadId, context] of threadContexts) {
    if (context.preparing && context.parametersList.length > 0) {
      if (context.parametersList.length === 1) {
        sqlStatements.push(processSQLStatement(context.preparing, context.parametersList[0]))
      } else {
        sqlStatements.push(processBatchSQLStatement(context.preparing, context.parametersList))
      }
    }
  }

  if (sqlStatements.length === 0) {
    throw new Error('未找到有效的SQL语句，请检查日志格式')
  }

  return sqlStatements
}

// 提取线程ID
function extractThreadId(line) {
  // 匹配常见的线程ID格式，如 [qtp1342643327-187] 或 [Thread-123]
  const threadMatch = line.match(/\[([\w-]+)\]/)
  if (threadMatch) {
    return threadMatch[1]
  }
  // 如果没有线程ID，返回默认值
  return 'default'
}

// 判断是否应该结束SQL收集
function shouldEndSQLCollection(line, context) {
  // 如果当前行包含MyBatis的执行标识，不结束收集
  if (line.includes('==>') || line.includes('<==')) {
    return false
  }
  
  // 如果当前行是新的Preparing行，不在这里结束（会在Preparing处理中结束）
  if (line.includes('Preparing:')) {
    return false
  }
  
  // 如果当前行是Parameters行，不结束收集
  if (line.includes('Parameters:')) {
    return false
  }
  
  // 检查是否是明显的其他SQL操作或日志结束
  // 1. 包含其他SQL关键字的行
  if (/\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)\b/i.test(line)) {
    return true
  }
  
  // 2. 包含异常或错误信息的行
  if (/\b(ERROR|Exception|Failed|Error)\b/i.test(line)) {
    return true
  }
  
  // 3. 包含新的业务日志的行（非SQL执行相关）
  if (/\b(INFO|WARN|DEBUG)\b/.test(line) && !line.includes('==>') && !line.includes('<==')) {
    // 只有当这是一个明显不同的日志行时才结束
    // 检查是否是同一个线程的相关日志
    const currentThreadId = extractThreadId(line)
    const contextThreadId = extractThreadId(context.preparing || '')
    
    // 如果是不同的线程或者包含明显不同的包名，则结束收集
    if (currentThreadId !== contextThreadId || 
        (line.includes('.') && !line.includes(getPackageFromPreparing(context.preparing)))) {
      return true
    }
  }
  
  // 4. 其他情况暂时不结束，继续收集（更保守的策略）
  return false
}

// 从Preparing语句中提取包名信息
function getPackageFromPreparing(preparing) {
  if (!preparing) return ''
  // 这里可以根据实际情况提取包名信息
  // 当前简化处理，直接返回空字符串
  return ''
}

// 提取Preparing行的SQL模板
function extractPreparing(line) {
  // 更宽松的正则表达式，处理包含额外信息的日志格式
  const preparingMatch = line.match(/Preparing:\s*(.+)$/)
  if (!preparingMatch) {
    throw new Error('无法识别Preparing行格式: ' + line)
  }
  return preparingMatch[1].trim()
}

// 提取Parameters行的参数
function extractParameters(line) {
  const parametersMatch = line.match(/Parameters:\s*(.*)$/)
  if (!parametersMatch) {
    throw new Error('无法识别Parameters行格式: ' + line)
  }
  
  const paramsStr = parametersMatch[1].trim()
  
  // 特殊处理单个 null 值的情况
  if (paramsStr === 'null') {
    return [{ value: 'null', type: '' }]
  }
  
  // 处理空参数的情况
  if (!paramsStr || paramsStr === '') {
    return []
  }

  const params = []
  // 改进的参数解析：先按逗号分割，再解析每个参数
  const paramSegments = paramsStr.split(/,\s*/)
  
  for (const segment of paramSegments) {
    const trimmedSegment = segment.trim()
    if (!trimmedSegment) continue
    
    // 匹配三种格式：
    // 1. value(Type) - 正常参数
    // 2. (Type) - 空参数
    // 3. value - 无类型参数
    const paramMatch = trimmedSegment.match(/^(?:([^()]*?))?(\([^)]+\))?$/)
    
    if (paramMatch) {
      const value = paramMatch[1] ? paramMatch[1].trim() : ''
      const type = paramMatch[2] ? paramMatch[2].trim() : ''
      
      // 对于只有类型的情况（如 (String)），值为空字符串
      if (!value && type) {
        params.push({ value: '', type })
      } else if (value || !type) {
        // 如果有值或者没有类型（包括单独的 null），都添加参数
        params.push({ value: value || trimmedSegment, type })
      }
    }
  }

  return params
}

// 处理SQL语句和参数
function processSQLStatement(preparingSQL, parameters) {
  const placeholders = (preparingSQL.match(/\?/g) || []).length
  
  // 检查参数数量是否匹配
  if (placeholders !== parameters.length) {
    // 提供更详细的错误信息
    let errorMsg = `参数数量不匹配：SQL中有${placeholders}个占位符，但提供了${parameters.length}个参数\n`
    errorMsg += `SQL: ${preparingSQL}\n`
    errorMsg += `参数: ${parameters.map(p => `${p.value}(${p.type})`).join(', ')}`
    
    // 尝试智能处理参数不匹配的情况
    if (parameters.length > placeholders) {
      console.warn('警告：参数多于占位符，将忽略多余的参数')
      parameters = parameters.slice(0, placeholders)
    } else {
      throw new Error(errorMsg)
    }
  }

  let processedSQL = preparingSQL
  let paramIndex = 0

  // 如果没有占位符，直接返回原始SQL
  if (placeholders === 0) {
    return {
      original: preparingSQL,
      processed: preparingSQL,
      parameters: parameters
    }
  }

  // 替换每个?占位符
  processedSQL = processedSQL.replace(/\?/g, () => {
    const param = parameters[paramIndex++]
    return formatParameter(param.value, param.type)
  })

  return {
    original: preparingSQL,
    processed: processedSQL,
    parameters: parameters
  }
}

// 处理批量SQL语句
function processBatchSQLStatement(preparingSQL, parametersList) {
  // 获取SQL类型
  const sqlType = getSQLType(preparingSQL)
  
  if (sqlType === 'INSERT') {
    return processBatchInsert(preparingSQL, parametersList)
  } else if (sqlType === 'UPDATE') {
    return processBatchUpdate(preparingSQL, parametersList)
  } else if (sqlType === 'DELETE') {
    return processBatchDelete(preparingSQL, parametersList)
  } else {
    // 其他类型的SQL（如SELECT），返回第一个
    return processSQLStatement(preparingSQL, parametersList[0])
  }
}

// 获取SQL语句类型
function getSQLType(sql) {
  const upperSQL = sql.toUpperCase().trim()
  if (upperSQL.startsWith('INSERT')) return 'INSERT'
  if (upperSQL.startsWith('UPDATE')) return 'UPDATE'
  if (upperSQL.startsWith('SELECT')) return 'SELECT'
  if (upperSQL.startsWith('DELETE')) return 'DELETE'
  return 'OTHER'
}

// 处理批量INSERT语句
function processBatchInsert(preparingSQL, parametersList) {
  const placeholders = (preparingSQL.match(/\?/g) || []).length
  
  // 解析INSERT语句结构
  const insertMatch = preparingSQL.match(/INSERT\s+INTO\s+(\S+)\s*\((.*?)\)\s*VALUES\s*\((.*?)\)/i)
  if (!insertMatch) {
    throw new Error('无法解析INSERT语句格式: ' + preparingSQL)
  }
  
  const tableName = insertMatch[1]
  const columns = insertMatch[2].trim()
  const valuePlaceholders = insertMatch[3]
  
  console.log(`处理批量INSERT: 表=${tableName}, 参数组数=${parametersList.length}`)
  
  // 构建批量INSERT语句
  let batchSQL = `INSERT INTO ${tableName} (${columns}) VALUES`
  const formattedValues = []
  
  for (let i = 0; i < parametersList.length; i++) {
    const parameters = parametersList[i]
    
    // 检查参数数量
    if (placeholders !== parameters.length) {
      console.warn(`批量INSERT第${i+1}行参数不匹配：SQL中有${placeholders}个占位符，但提供了${parameters.length}个参数`)
      // 对于参数不匹配的情况，尝试处理而不是抛出错误
      if (parameters.length < placeholders) {
        // 参数不足，跳过这一行
        continue
      }
      // 参数过多，截取前面的参数
      parameters.splice(placeholders)
    }
    
    // 替换占位符
    let valueStr = valuePlaceholders
    let paramIndex = 0
    valueStr = valueStr.replace(/\?/g, () => {
      const param = parameters[paramIndex++]
      return formatParameter(param.value, param.type)
    })
    
    formattedValues.push(`  (${valueStr})`)
  }
  
  if (formattedValues.length === 0) {
    throw new Error('批量INSERT处理后没有有效的数据行')
  }
  
  // 构建最终的批量SQL
  batchSQL += '\n' + formattedValues.join(',\n') + ';'
  
  return {
    original: preparingSQL,
    processed: batchSQL,
    parameters: parametersList.flat(),
    isBatch: true,
    batchCount: formattedValues.length,
    description: `批量插入操作 - ${formattedValues.length}条记录`
  }
}

// 处理批量UPDATE语句
function processBatchUpdate(preparingSQL, parametersList) {
  // UPDATE不支持批量语法，生成多个UPDATE语句
  const statements = []
  
  for (let i = 0; i < parametersList.length; i++) {
    const stmt = processSQLStatement(preparingSQL, parametersList[i])
    statements.push(stmt.processed)
  }
  
  const batchSQL = statements.join(';\n') + ';'
  
  return {
    original: preparingSQL,
    processed: batchSQL,
    parameters: parametersList.flat(),
    isBatch: true,
    batchCount: parametersList.length
  }
}

// 处理批量DELETE语句
function processBatchDelete(preparingSQL, parametersList) {
  // DELETE不支持批量语法，生成多个DELETE语句
  const statements = []
  
  for (let i = 0; i < parametersList.length; i++) {
    const parameters = parametersList[i]
    const stmt = processSQLStatement(preparingSQL, parameters)
    
    // 尝试添加注释，从参数中提取有意义的信息
    let comment = ''
    // 查找ID参数（通常是第一个参数）
    if (parameters.length > 0 && parameters[0].value) {
      const idValue = parameters[0].value
      // 如果是UUID格式的ID，只显示前8位
      if (idValue.match(/^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i)) {
        comment = `-- 删除记录: ${idValue.substring(0, 8)}...`
      } else {
        comment = `-- 删除记录: ${idValue}`
      }
    }
    
    statements.push(comment ? `${comment}\n${stmt.processed}` : stmt.processed)
  }
  
  const batchSQL = statements.join(';\n') + ';'
  
  return {
    original: preparingSQL,
    processed: batchSQL,
    parameters: parametersList.flat(),
    isBatch: true,
    batchCount: parametersList.length
  }
}

// 格式化参数值
function formatParameter(value, type) {
  // 特殊处理 'null' 字符串值
  if (value === 'null' && !type) {
    // 当参数值是 'null' 且没有类型时，作为字符串处理
    return "'null'"
  }
  
  if (value === null || (value === 'null' && type)) {
    return 'NULL'
  }

  // 处理空字符串参数
  if (value === '') {
    // 如果是数字类型的空值，返回NULL
    if (type.includes('Integer') || type.includes('Long') || type.includes('Double') || type.includes('Float')) {
      return 'NULL'
    }
    // 字符串类型的空值返回空字符串
    return "''"
  }

  // 处理不同类型的参数
  if (type.includes('Integer') || type.includes('Long') || type.includes('Double') || type.includes('Float')) {
    return value
  } else if (type.includes('Boolean')) {
    return value.toLowerCase() === 'true' ? '1' : '0'
  } else if (type.includes('Timestamp') || type.includes('Date')) {
    return `'${escapeString(value)}'`
  } else {
    // 默认作为字符串处理
    return `'${escapeString(value)}'`
  }
}

// 转义字符串中的特殊字符
function escapeString(str) {
  return str.replace(/'/g, "''").replace(/\\/g, "\\\\")
}